home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / AHDI / TTINST / HINSTALL.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  15.3 KB  |  670 lines

  1. /* hinstall.c */
  2.  
  3. /*
  4.  * Install hard disk driver on hard disk
  5.  *
  6.  * Copyright 1988 Atari Corp.
  7.  * All Rights Reserved.
  8.  *
  9.  * Jul-18-1989    ml.    Have to mask off bits that don't correspond
  10.  *            to unit number when using the pun structure.
  11.  * Feb-06-1990    ml.    Removed code that handles MSDOS-format drives.
  12.  */
  13.  
  14. #include "hinstall.h"
  15. #include "defs.h"
  16. #include "part.h"
  17. #include <obdefs.h>
  18. #include <gemdefs.h>
  19. #include <osbind.h>
  20.  
  21.  
  22. /*  AES (windows and messages) related variables */
  23. int gl_hchar;        /* height of system font (pixels) */
  24. int gl_wchar;        /* width of system font (pixels) */
  25. int gl_wbox;        /* width of box able to hold system font */
  26. int gl_hbox;        /* height of box able to hold system font */
  27.  
  28. int phys_handle;    /* physical workstation handle */
  29. int handle;        /* virtual workstation handle */
  30. int wi_handle;        /* window handle */
  31. int top_window;        /* handle of topped window */
  32.  
  33. int xdesk, ydesk, hdesk, wdesk;    /* window X, Y, width, height */
  34. int xold, yold, hold, wold;
  35. int xwork, ywork, hwork, wwork;    /* desktop and work areas */
  36.  
  37. int msgbuff[8];        /* event message buffer */
  38. int keycode;        /* keycode returned by event-keyboard */
  39. int mx, my;        /* mouse x and y pos. */
  40. int butdown;        /* button state tested for, UP/DOWN */
  41. int ret;        /* dummy return variable */
  42.  
  43. int hidden;        /* current state of cursor */
  44.  
  45. int contrl[12];
  46. int intin[128];
  47. int ptsin[128];
  48. int intout[128];
  49. int ptsout[128];    /* storage wasted for idiotic bindings */
  50.  
  51. int work_in[11];    /* Input to GSX parameter array */
  52. int work_out[57];    /* Output from GSX parameter array */
  53. int pxyarray[10];    /* input point array */
  54.  
  55. /* User interface variables */
  56. /* Dialogue boxes */
  57. extern OBJECT *menubar;        /* menu bar */
  58. extern OBJECT *about;        /* release date of this version */
  59. extern OBJECT *logdev;        /* logical device numbers */
  60. extern OBJECT *instfnl;        /* final warning for installing driver */
  61. extern OBJECT *unstfnl;        /* final warning for removing driver */
  62.  
  63. /* Error messages */
  64. extern char *nomemory;        /* not enough memory */
  65. extern char *noavdrv;        /* no available drive for installation */
  66. extern char *cantinst;        /* cannot install driver */
  67. extern char *rootread;        /* root sector read error */
  68. extern char *rootwrit;        /* root sector write error */
  69. extern char *bootread;        /* boot sector read error */
  70. extern char *bootwrit;        /* boot sector write error */
  71. extern char *wrdvrerr;        /* error when writing driver */
  72. extern char *crdvrerr;        /* error when creating driver destination */
  73. extern char *opdvrerr;        /* error when opening driver source */
  74. extern char *nodriver;        /* no existing driver on disk */
  75.  
  76. /* Globals */
  77. static char *rscorrupt = "[3][Fatal Error!|Corrupt Resource File][EXIT]";
  78. char sbuf[512];            /* error message buffer */
  79. int running;            /* 1: continue evnt_multi() loop */
  80. int physdev[MAXLOGDEVS];    /* physical unit # for the logical drives */
  81.  
  82. long ostack;            /* old system stack */
  83. int *pun;            /* pointer to # of physical units exist */
  84. int *vernum;            /* --> AHDI version #; 0 if not available */
  85.  
  86.  
  87. /*
  88.  * Top level;
  89.  * we get control from the desktop.
  90.  *
  91.  */
  92. main()
  93. {
  94.     long *cookptr;    /* pointer to AHDI cookie */
  95.  
  96.     running = TRUE;
  97.     appl_init();
  98.     phys_handle = graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox);
  99.     wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
  100.     open_vwork();
  101.     wi_handle = wind_create(WI_KIND, xdesk, ydesk, wdesk, hdesk);
  102.   
  103.     hidden = FALSE;
  104.     butdown = TRUE;
  105.   
  106.     if (!rsrc_load(RESOURCEFILE)) {
  107.     errs("[2][", RESOURCEFILE, "][ OK ]");
  108.     goto punt;
  109.     }
  110.   
  111.     graf_mouse(ARROW, 0L);
  112.   
  113.     /* display menu bar */
  114.     if (getalladdr() == ERROR) {
  115.     errs("[2][", RESOURCEFILE, "][ OK ]");
  116.     goto punt;
  117.     }
  118.   
  119.     ostack = Super(NULL);    /* Superuser mode for low memory access */
  120.     pun = (int *)(*(long *)PUNPTR);
  121.     Super(ostack);        /* back to User mode */
  122.  
  123.     if (!pun || !(*pun)) {    /* if no unit exists */
  124.     err(noavdrv);        /* return error */
  125.     goto punt;
  126.     }
  127.  
  128.     cookptr = (long *)((char *)pun + 2 + 16 + 16*4);
  129.     if (*cookptr != AHDI || cookptr != *(long *)(cookptr + 1))
  130.     vernum = 0L;
  131.     else
  132.     vernum = (int *)(cookptr + 2);
  133.  
  134.     menu_bar(menubar, 1);    /* put up menu bar */
  135.   
  136.     while (running)
  137.     domulti();
  138.     
  139.     menu_bar(menubar, 0);    /* erase menu bar */
  140.   
  141. punt:
  142.     wind_delete(wi_handle);    /* close window on screen */
  143.     v_clsvwk(handle);        /* close virtual workstation */
  144.     appl_exit();        /* exit application HDX */
  145.     Pterm(0);            /* terminate process */
  146. }
  147.  
  148.  
  149. /*
  150.  * Get a single event, process it, and return.
  151.  *
  152.  */
  153. domulti(){
  154.     int event;
  155.   
  156.     event = evnt_multi(MU_MESAG,
  157.             1,1,butdown,
  158.             0,0,0,0,0,
  159.             0,0,0,0,0,
  160.             msgbuff,0,0,&mx,&my,&ret,&ret,&keycode,&ret);
  161.   
  162.     if (event & MU_MESAG)
  163.         switch (msgbuff[0]) {
  164.         case WM_REDRAW:
  165.         do_redraw(msgbuff[4],msgbuff[5],msgbuff[6],msgbuff[7]);
  166.         break;
  167.     
  168.         case WM_NEWTOP:
  169.         case WM_TOPPED:
  170.         wind_set(wi_handle, WF_TOP, 0, 0, 0, 0);
  171.         break;
  172.     
  173.         case WM_CLOSED:
  174.         running = FALSE;
  175.         break;
  176.     
  177.         case MN_SELECTED:
  178.         graf_mouse(HOURGLASS, 0L);
  179.         switch(msgbuff[3]) {
  180.             case MNDESK:
  181.             if(msgbuff[4] == DEABOUT) {
  182.                 strcpy((about[ABVERSN].ob_spec)->te_ptext, "4.03");
  183.                 about[ABOK].ob_state = NORMAL;
  184.                 execform(about);
  185.                 }
  186.             break;        /* "cannot happen" */
  187.  
  188.             case MNFILE:
  189.             switch (msgbuff[4]) {
  190.                 case FIQUIT:    /* [QUIT] item */
  191.                 running = 0;
  192.                 break;
  193.  
  194.                 case FIINST:    /* [INSTALL] item */
  195.                 install();
  196.                 break;
  197.         
  198.                 case FIUNINST:    /* [UNINSTALL] item */
  199.                 uninstall();
  200.                 break;
  201.             }
  202.             break;
  203.         }
  204.         menu_tnormal(menubar, msgbuff[3], 1); /* back to normal */
  205.             graf_mouse(ARROW, 0L);    /* restore mouse */
  206.         break;
  207.     }
  208. }
  209.  
  210.  
  211. /*
  212.  * Install hard disk driver.
  213.  *
  214.  */
  215. install()
  216. {
  217.     int i, pdev, ldev;
  218.     int maxsiz;
  219.     char *s, *d, sdev, dvr[15];
  220.     char *lbuf;
  221.     extern char rootstart, rootend;
  222.     extern char bootstart, bootend;
  223.  
  224.     if ((ldev = glogdev()) < 0) 
  225.     return BAILOUT;
  226.   
  227.     /* final warning */
  228.     sdev = ldev + 'C';
  229.     (instfnl[INSTDRV].ob_spec)->te_ptext = &sdev;
  230.     instfnl[INSTOK].ob_state = NORMAL;
  231.     instfnl[INSTCN].ob_state = NORMAL;
  232.     if (execform(instfnl) != INSTOK) return BAILOUT;
  233.  
  234.     /* find maximum sector size on system */
  235.     if (!vernum)        /* new version of AHDI? */
  236.     maxsiz = 512;        /* if not, sector size is always 512 bytes */
  237.     else
  238.     maxsiz = *(vernum + 1);    /* max sector size kept after version # */
  239.  
  240.     if (!(lbuf = Malloc((long)maxsiz))) {
  241.     err(nomemory);
  242.     return ERROR;
  243.     }
  244.  
  245.     /* find which physical unit the chosen logical drive belongs to */
  246.     pdev = physdev[ldev];
  247.     pdev &= 0x0f;        /* mask off extra bits */
  248.       
  249.     /* Remove old driver if there is one */
  250.     dvr[0] = sdev;
  251.     strcpy(&dvr[1], OLDDVR);
  252.     if (!(Fsfirst(dvr, 0x04)))    /* 0x04 = system files */
  253.     Fdelete(dvr);
  254.           
  255.   
  256.     /* copy driver to specified unit */
  257.     if (copydvr(sdev) != OK)
  258.     return ERROR;
  259.  
  260.     /* read in the root sector */
  261.     if (getroot(pdev, lbuf) != 0) {
  262.     err(rootread);
  263.     goto argh;
  264.     }
  265.   
  266.     /* copy boot code into root sector */
  267.     for (d = lbuf, s = &rootstart, i = &rootend - &rootstart; i--;)
  268.     *d++ = *s++;
  269.  
  270.     /* if gemroot() is not successful, return with error */
  271.     if (gemroot(lbuf, 1) != 0) {
  272.     err(cantinst);
  273.     goto argh;
  274.     }
  275.  
  276.     /* write installed root sector back to disk */  
  277.     if (putroot(pdev, lbuf) != 0) {
  278.     err(rootwrit);
  279.     goto argh;
  280.     }
  281.  
  282.     /* read boot sector from partition */
  283.     if (getboot(ldev, lbuf) != 0) {
  284.     err(bootread);
  285.     goto argh;
  286.     }
  287.  
  288.     /* 
  289.      * copy boot code to boot sector, avoiding the BPB information 
  290.      * copy bytes 0..1 for BRA.S to code;
  291.      * leave bytes 2..$1d unaltered (information for BPB);
  292.      * copy bytes $1e..$1fe for code.
  293.      */
  294.     s = &bootstart;
  295.     d = lbuf;
  296.     *d++ = *s++;
  297.     *d++ = *s++;
  298.     d += 0x1c;
  299.     s += 0x1c;
  300.     for (i = &bootend-&bootstart-0x1e; i--;)
  301.     *d++ = *s++;
  302.  
  303.     /* make the image executable */
  304.     Protobt(lbuf, -1L, -1, 1);
  305.  
  306.     /* write the installed boot sector back to disk */
  307.     if (putboot(ldev, lbuf) != 0) {
  308.     err(bootwrit);
  309.     goto argh;
  310.     }
  311.  
  312.     return;
  313.  
  314. argh:
  315.     dvr[0] = sdev;
  316.     strcpy(&dvr[1], DVRNAME);
  317.     Fdelete(dvr);
  318. }
  319.  
  320.  
  321. /*
  322.  * gemroot(buf, flg)
  323.  * char buf[]
  324.  * int flg    (0: clear boot bit;  non-0: set boot bit)
  325.  */
  326. gemroot(buf, flg)
  327. char buf[];
  328. int flg;
  329. {
  330.     GEMPART *gpart, *gpart1;
  331.     int pno;
  332.  
  333.     /* point to beginning of partition map */
  334.     gpart = gpart1 = &((RSECT *)(buf + 0x200 - sizeof(RSECT)))->hd_p[0];
  335.  
  336.     /* clear all boot bits */
  337.     for (pno = 0; pno < NPARTS; pno++, gpart1++) {
  338.     gpart1->p_flg &= ~P_BOOTBIT;
  339.     }
  340.  
  341.     if (!flg) {
  342.     Protobt(buf, -1L, -1, 1);
  343.     return OK;
  344.     }
  345.  
  346.     /* find the first valid partition and set its boot bit */
  347.     for (pno = 0; pno < NPARTS; pno++, gpart++) {
  348.     if (gpart->p_flg & P_EXISTS &&
  349.         gpart->p_siz) {         /* if partition exists */
  350.         if ((gpart->p_id[0] == 'G' &&    /* and it's a GEM partition */
  351.              gpart->p_id[1] == 'E' &&
  352.              gpart->p_id[2] == 'M') ||
  353.         (gpart->p_id[0] == 'B' &&
  354.          gpart->p_id[1] == 'G' &&
  355.          gpart->p_id[2] == 'M')) {
  356.             gpart->p_flg |= P_BOOTBIT;    /* set the boot bit */
  357.             Protobt(buf, -1L, -1, 1);    /* make image executable */
  358.             return OK;            /* return successful */
  359.         }
  360.     }
  361.     }
  362.     return ERROR;    /* if cannot find valid partition, return error */
  363. }
  364.  
  365.  
  366. /*
  367.  *  Remove bootable driver from hard disk.
  368.  */
  369. uninstall()
  370. {
  371.     int i, pno;
  372.     int dev, ldev;
  373.     char sdev;
  374.     char sect[512];
  375.     long ostack;
  376.     char dvr[15];    /* entire path name of driver has at most 17 char */ 
  377.  
  378.     if ((ldev = glogdev()) < 0) 
  379.     return BAILOUT;
  380.   
  381.     /*
  382.      * Make sure they're sure...
  383.      */
  384.     sdev = ldev + 'C';
  385.     (unstfnl[UNSTDRV].ob_spec)->te_ptext = &sdev;
  386.     unstfnl[UNSTOK].ob_state = NORMAL;
  387.     unstfnl[UNSTCN].ob_state = NORMAL;
  388.     if (execform(unstfnl) != UNSTOK) return BAILOUT;
  389.  
  390.     /* find which physical unit the chosen logical drive belongs to */
  391.     dev = physdev[ldev];
  392.     dev &= 0x0f;        /* mask off extra bits */
  393.       
  394.     /* remove driver from disk */
  395.     dvr[0] = sdev;
  396.     strcpy(&dvr[1], DVRNAME);
  397.     if (Fdelete(dvr)) {
  398.     strcpy(&dvr[1], OLDDVR);
  399.     if (Fdelete(dvr)) {
  400.         err(nodriver);
  401.         goto back;
  402.     }
  403.     }
  404.   
  405.     /* unset boot bit of partition */
  406.     if (getroot(dev, sect) != 0) {
  407.     err(rootread);
  408.     goto back;
  409.     }
  410.  
  411.     ret = gemroot(sect, 0);
  412.   
  413.     if (putroot(dev, sect) != 0) {
  414.     err(rootwrit);
  415.     goto back;
  416.     }
  417.  
  418.     /* set bootdev to A: for future warm resets */
  419.     ostack = Super(0L);
  420.     *(int *)BOOTDEV = 0;
  421.     Super(ostack);
  422. back:
  423.     ;
  424. }
  425.  
  426.  
  427.  
  428. /*
  429.  * Copy hard disk driver to root of ldev:
  430.  */
  431. char dvrbuf[BUFSIZ];
  432. copydvr(sdev)
  433. char sdev;
  434. {
  435.     int ih, oh, ret;
  436.     long cnt;
  437.     char dvrdest[15];    /* path name of driver */ 
  438.  
  439.     if ((ih = Fopen(DVRSOURCE, 0)) < 0)
  440.     return err(opdvrerr);
  441.   
  442.     dvrdest[0] = sdev;
  443.     strcpy(&dvrdest[1], DVRNAME);
  444.     if ((oh = Fcreate(dvrdest, 0)) < 0) {
  445.     ret = err(crdvrerr);
  446.     goto copyr;
  447.     }
  448.  
  449.     while ((cnt = Fread(ih, BUFSIZ, dvrbuf)) > 0) {
  450.     if (Fwrite(oh, cnt, dvrbuf) != cnt) {
  451.         ret = err(wrdvrerr);
  452.         goto copyr;
  453.     }
  454.     }
  455.     ret = OK;        /* got here with no error */
  456.  
  457. copyr:
  458.     Fclose(ih);
  459.     Fclose(oh);
  460.     if (ret) Fdelete(dvrdest);
  461.     return ret;
  462. }
  463.  
  464.  
  465. /*
  466.  * Open virtual workstation.
  467.  *
  468.  */
  469. open_vwork()
  470. {
  471.     int i;
  472.   
  473.     for (i = 0; i < 9;)
  474.     work_in[i++] = 1;
  475.     work_in[10] = 2;
  476.     handle = phys_handle;
  477.     v_opnvwk(work_in, &handle, work_out);
  478. }
  479.  
  480.  
  481. /*
  482.  * Find and redraw all clipping rectangles
  483.  *
  484.  */
  485. do_redraw(xc, yc, wc, hc)
  486. int xc, yc, wc, hc;
  487. {
  488.     GRECT t1, t2;
  489.     int temp[4];
  490.   
  491.     wind_update(TRUE);
  492.     hide_mouse();
  493.     t2.g_x=xc;
  494.     t2.g_y=yc;
  495.     t2.g_w=wc;
  496.     t2.g_h=hc;
  497.     vsf_interior(handle, 1);
  498.     vsf_color(handle, 0);
  499.     wind_get(wi_handle, WF_FIRSTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  500.     while (t1.g_w && t1.g_h) {
  501.     if (rc_intersect(&t2, &t1)) {
  502.         set_clip(t1.g_x, t1.g_y, t1.g_w, t1.g_h);
  503.         temp[0] = xwork;
  504.         temp[1] = ywork;
  505.         temp[2] = xwork + wwork - 1;
  506.         temp[3] = ywork + hwork - 1;
  507.         v_bar(handle, temp);
  508.     }
  509.         wind_get(wi_handle, WF_NEXTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  510.     }
  511.   
  512.     show_mouse();
  513.     wind_update(FALSE);
  514. }
  515.  
  516.  
  517. /*
  518.  * Hide the mouse.
  519.  *
  520.  */
  521. hide_mouse()
  522. {
  523.     if (!hidden) {
  524.     graf_mouse(M_OFF, 0L);
  525.     hidden = TRUE;
  526.     }
  527. }
  528.  
  529.  
  530. /*
  531.  * Show the mouse.
  532.  *
  533.  */
  534. show_mouse() 
  535. {
  536.     if (hidden) {
  537.     graf_mouse(M_ON, 0L);
  538.     hidden = FALSE;
  539.     }
  540. }
  541.  
  542.  
  543. /*
  544.  * Set clipping rectangle.
  545.  *
  546.  */
  547. set_clip(x, y, w, h)
  548. int x, y, w, h;
  549. {
  550.     int clip[4];
  551.   
  552.     clip[0] = x;
  553.     clip[1] = y;
  554.     clip[2] = x + w;
  555.     clip[3] = y + h;
  556.     vs_clip(handle, 1, clip);
  557. }
  558.  
  559.  
  560. /*
  561.  * "Execute" form,
  562.  * return thingy that caused the exit.
  563.  *
  564.  */
  565. execform(tree)
  566.      OBJECT tree[];
  567. {
  568.     int thingy;
  569.     WORD formw, formh;
  570.     WORD lx, ly, sx, sy; 
  571.   
  572.     formw = tree[0].ob_width;
  573.     formh = tree[0].ob_height;
  574.   
  575.     sx = wdesk / 2;
  576.     sy = hdesk / 2;
  577.     lx = (wdesk - formw) / 2;
  578.     ly = (hdesk - formh) / 2;
  579.   
  580.     tree[0].ob_x = lx;                /* set form's location */
  581.     tree[0].ob_y = ly;
  582.   
  583.     graf_mouse(ARROW, 0L);
  584.     form_dial(0, sx, sy, 0, 0, lx, ly, formw, formh);
  585.     form_dial(1, sx, sy, 0, 0, lx, ly, formw, formh);
  586.     objc_draw(tree, 0, MAX_DEPTH, 0, 0, wdesk, hdesk);
  587.     thingy = form_do(tree, 0);
  588.     form_dial(2, sx, sy, 0, 0, lx, ly, formw, formh);
  589.     form_dial(3, sx, sy, 0, 0, lx-3, ly-3, formw+4, formh+4);
  590.     graf_mouse(HOURGLASS, 0L);
  591.     return thingy;
  592. }
  593.  
  594.  
  595. /*
  596.  * Complain about corrupt resource file
  597.  * and setup to return to the desktop.
  598.  *
  599.  */
  600. corrupt()
  601. {
  602.     err(rscorrupt);    /* complain */
  603.     running = FALSE;    /* stop multi calls */
  604.     return ERROR;    /* bubble up complaint */
  605. }
  606.  
  607.  
  608. /*
  609.  * Translate from logical device number
  610.  * to object number in logical device
  611.  * dialouge box.
  612.  */
  613. int logxlat[] = {
  614.     CCOLON, DCOLON, ECOLON, FCOLON,
  615.     GCOLON, HCOLON, ICOLON, JCOLON,
  616.     KCOLON, LCOLON, MCOLON, NCOLON,
  617.     OCOLON, PCOLON
  618. };
  619.  
  620.  
  621. /*
  622.  * Get logical device,
  623.  * return 'C'...'P'
  624.  * or -1.
  625.  *
  626.  */
  627. glogdev()
  628. {
  629.     char *puntbl;    /* ptr to physical unit table */
  630.     int cpun;        /* current physical unit number */
  631.     int clun;        /* current logical unit number */
  632.     int i;        /* index */
  633.  
  634.     /* assume no drives exist */
  635.     for (i = 0; i < MAXLOGDEVS; i++) {
  636.     logdev[logxlat[i]].ob_state = DISABLED;
  637.     }
  638.  
  639.     /* find out mapping of physical units to logical drives */
  640.     /* and selectively enable drive buttons */
  641.     puntbl = (char *)(pun + 2);    /* puntbl -> pun(C:) */
  642.     cpun = -1;            /* start with a bad physical unit # */
  643.  
  644.     /* logical drive is selectable only if it belongs to a valid */
  645.     /* physical unit and it is the first partition of the unit */
  646.     for (i = 0;
  647.      (i < MAXLOGDEVS) && ((int)(*puntbl) != -1); 
  648.      i++, puntbl++) {
  649.     if (cpun != (int)(*puntbl)) {
  650.         cpun = (int)(*puntbl);
  651.         logdev[logxlat[i]].ob_state = NORMAL;
  652.     }
  653.     physdev[i] = cpun;    /* remember which pun it belongs to */
  654.     }
  655.  
  656.     logdev[LOGOK].ob_state = NORMAL;
  657.     logdev[LOGCN].ob_state = NORMAL;
  658.  
  659.     if (execform(logdev) != LOGOK) return -1;
  660.  
  661.     for (i = 0; i < MAXLOGDEVS; ++i)
  662.     if (logdev[logxlat[i]].ob_state & SELECTED)
  663.         return i;
  664.  
  665.     return -1;
  666. }
  667.  
  668.  
  669.  
  670.